// ***************************** //
// Initizalizing System Variable //
// ***************************** //
var requestIteration = { '1': 0, '2': 0 } ; // Variable to check iteration requests for any type
var standardIdleTime = 4 * 1000; // Seconds between iteration on unknown error
var randomMeme;
var requestTimeout = 15 * 1000; // Time before Timeout.
var randomMemeDelay = 1000 * 60 * 10; // Time between Random Meme calls.
var iterateWaiting = 0; // Queue for iterating function

var UNREADCOUNTER = 1;
var RANDOMMEME = 2;

// Initialize LogLevel for loggin operation
if( !localStorage.logLevel )
	localStorage.logLevel = 0;

// Checking parameters
if( !checkConsistency() ) return;

// Radom Meme Behavior
if(( localStorage.showRandomMeme || 'show' ) == 'show' )
	getRandomMeme();
 

writeLog( 'Random Meme behavior: ' + localStorage.showRandomMeme, LOG_INFO );

// Using local variables from the localStorage.
writeLog( 'Setting Username as ' + localStorage.username, LOG_INFO );
writeLog( 'Setting Request Delay as ' + localStorage.requestDelay, LOG_INFO );

// Getting Options
var notification = localStorage.notification;

// Get Notification.
unreadCounter();


// ************************************************************************* //
// ** Functions ************************************************************ //
// ************************************************************************* //

// Checking parameters to be valid
function checkConsistency() {
	var param
	var check = false;
			
	// Checking delay between requests
	if( isNaN( param = localStorage.requestDelay ) || param < 30 ) {
		writeLog( 'Request Delay value not in Range: ' + param, LOG_WARNING ); 
		localStorage.requestDelay = 90000; 
		check = true; }
	// Checking username validity
	else if( 	
			!( param = localStorage.username ) || 
			   param == '' || 
			   param === undefined || 
			   param == null 
		) {
		writeLog( 'Wrong username: ' + param, LOG_ERROR );
		errorHandler( 'Opt' ); }
	else
		check = true;
	return check;
}

function unreadCounter() {
	if( !checkConsistency() ) return;
	
	var page = getMeemiAPIURL( 'notify' );

	var parameters = {
		'meemi_id': localStorage.username,
		'pwd': localStorage.password,
		'app_key': applicationKey };
	
	// Sending request for notification
	$.ajax({
		'url': page,
		'type': 'POST',
		'data': parameters,
		'timeout': requestTimeout,
		'dataType': 'json',
		'success': function( data ) {
			// In case of success of sending data
			var badgeValue = 0;
			
			writeLog( 'Retrieved Meme Counter', LOG_INFO );
			writeLog( JSON.stringify( data ), LOG_MOREINFO );
			
			try {
				// Meemi can return also an error, in this case the error will be displayed
				if( data.error ) {
					var errorCode = data.error.code;
					writeLog( 'Unread counter error: ' + errorCode, LOG_ERROR );
					if( 
						errorCode == 5 || // password non valida
						errorCode == 8 || //non sei loggato
						errorCode == 2 || // l'utente non esiste
						errorCode == 4 || // utente non valido
						errorCode == 6 ) { // l'utente non esiste
							errorHandler( 'Opt' ); }
					else
						errorHandler( 'Err' );
					iterateRequest( unreadCounter, requestTimeout, localStorage.requestDelay, UNREADCOUNTER ); }
				else {
					notification = JSON.parse( localStorage.notification );
					$.each( data, function( key, val ) {
						if( notification[key] ) {
							badgeValue += val; }
					});
					
					chrome.browserAction.setBadgeText({ 'text': badgeValue == 0 ? '' : badgeValue.toString() });
					localStorage.notificationCount = JSON.stringify( data );
					iterateRequest( unreadCounter, -1, localStorage.requestDelay, UNREADCOUNTER );
				} }					

			// Check if something goes wrong.
			catch( exception ) {
				writeLog( 'Unexpected unread counter error: ' + exception, LOG_ERROR );
				iterateRequest( unreadCounter, requestTimeout, localStorage.requestDelay, UNREADCOUNTER );
				} },
		'error': function( xhr, textStatus, thrownError ) {
			
			if( textStatus == 'timeout' ) {
				writeLog( 'Unread counter timeout after ' + requestTimeout / 1000 + ' seconds.', LOG_WARNING );
				errorHandler( 'TOut' ); }
			else {
				writeLog( 'Unread counter error: ' + textStatus, LOG_ERROR );
				writeLog( 'XMLHttpRequest: ' + xhr.responseText, LOG_MOREINFO );
				errorHandler( 'Err' ); }
					
			localStorage.lastError = textStatus;
			iterateRequest( unreadCounter, standardIdleTime, localStorage.requestDelay, UNREADCOUNTER ); }
	});
}

// *************** //
// Iterate request //
// *************** //
// Checking if it's not iterated yet.
function iterateRequest( iteratingFunction, timeDelay, functionDelay, functionID ) {
	// Checking if function is already queued, then exit.
	if( iterateWaiting & functionID ) {
		writeLog( 'Function n.' + functionID + ' already waiting: ' + iterateWaiting, LOG_INFO );
		return };
			
	// Check if timeDelay is in millisencond.
	if( timeDelay < 1000 ) timeDelay = timeDelay * 1000;
	// Adding function to the waiting list.
	iterateWaiting += functionID;
	// If previously iteration was a success.
	if( timeDelay < 0 ) {
		requestIteration[functionID] = 0;
		window.setTimeout( function() {
			writeLog( 'First attempt: ' + functionID, LOG_INFO );
			iterateWaiting -= functionID;
			iteratingFunction(); }, functionDelay ); }
	else {
		requestIteration[functionID]++;
		if( requestIteration[functionID] <= 10 )
			window.setTimeout( function() {
				writeLog( 'Requesting quick iteration: ' + requestIteration[functionID] + ' for function: ' + functionID, LOG_WARNING );
				iterateWaiting -= functionID;
				iteratingFunction(); }, timeDelay );
		else
			window.setTimeout( function() {
				writeLog( 'Requesting delayed iteration: ' + requestIteration[functionID] + ' for function: ' + functionID, LOG_WARNING );
				iterateWaiting -= functionID;
				iteratingFunction(); }, functionDelay );
		}
}

// ******************* //
// Random Meme request //
// ******************* //
function getRandomMeme() {
		
	if( !checkConsistency() ) return;
	var page = getMeemiAPIURL( '', localStorage.username, '/wf/limit_30' );
	
	var parameters = {
	'meemi_id': localStorage.username,
	'pwd': localStorage.password,
	'app_key': applicationKey };
	
	$.ajax({
		'url': page,
		'type': 'POST',
		'data': parameters,
		'timeout': requestTimeout,
		'dataType': 'json',
		'success': function( data ) {

			writeLog( 'Retrieved Random Meme List', LOG_INFO );
					
			try {
				// Meemi can return also an error, in this case, error will be displayed
				if( data.error ) {
					writeLog( 'Ramdom meme error: '+ data.error.code, LOG_ERROR );
					iterateRequest( getRandomMeme, requestTimeout, randomMemeDelay, RANDOMMEME ); }
				else {
					var randomNumber = Math.round( Math.random() * ( data.length -1 ));
					if( randomNumber < 0 ) randomNumber = 0;
					randomMeme = data[randomNumber];
					
					writeLog( 'Random number: '+ randomNumber, LOG_INFO );
					writeLog( 'Random meme URL: '+ 'http://meemi.com/'+ randomMeme.screen_name+ '/'+ randomMeme.id, LOG_INFO );

					iterateRequest( getRandomMeme, -1, randomMemeDelay, RANDOMMEME );
				} }					

			// Check if something goes wrong.
			catch( exception ) {
				writeLog( 'Unexpected error: ' + exception, LOG_ERROR );
				iterateRequest( getRandomMeme, requestTimeout, randomMemeDelay, RANDOMMEME );
				} },
		'error': function( xhr, textStatus, thrownError ) {
					
			if( textStatus == 'timeout' ) {
				writeLog( 'Random Meme Timeout after ' + requestTimeout / 1000 + ' seconds.', LOG_WARNING );
				errorHandler( 'TOut' ); }
			if( textStatus == 'parsererror' ) {
				writeLog( 'Error while parsig random meme.', LOG_ERROR );
				writeLog( 'JSON url: '+ page, LOG_INFO );
				if( /^<.xml/.test( xhr.responseText )) {
					writeLog( 'XML response instead of JSON', LOG_WARNING );
					writeLog( 'XML: '+ xhr.responseText, LOG_MOREINFO ); }
				else {
					writeLog( 'Manual parsing JSON.', LOG_WARNING );
					writeLog( 'Invalid JSON: '+ xhr.responseText, LOG_MOREINFO );
					// Manual parsing of the file
					var data = xhr.responseText.split( /\}\,\{/ );
					var jsonData = [];
					// Excluding wrong json object
					if( data )
						$.each( data, function( index, value ) {
							// If first occurence has '[' delete it
							if( index == 0 && /^\[/.test( value )) {
								value = value.substr( 1 );
								value = value+ '}'; }
							// If last occurence has ']' delete it
							else if( index == jsonData.length -1 && /\]$/.test( value ) ) {
								value = value.substr( 0, value.length -2 );
								value = '{'+ value; }
							else
							// Adding brackets to other
								value = '{'+ value+ '}';
							try{	jsonData.push( JSON.parse( value )); }
							catch( exception ) {
								var memeId = /\"id\"\:(\d*)\,/.exec( value );
								var memeAuthor = /\"screen_name\"\:\"(\w*)\"\,/.exec( value );
								writeLog( 'Found invalid JSON meme: http://meemi.com/'+ memeAuthor[1]+ '/'+ memeId[1], LOG_INFO ); }
						}); 
				
					// Extracting RandomMeme
					var randomNumber = Math.round( Math.random() * ( jsonData.length -1 ));
					if( randomNumber < 0 ) randomNumber = 0;
					randomMeme = jsonData[randomNumber];
					
					writeLog( 'Random number: '+ randomNumber, LOG_INFO );
					writeLog( 'Random meme URL: '+ 'http://meemi.com/'+ randomMeme.screen_name+ '/'+ randomMeme.id, LOG_INFO );

					// Iterating as success
					iterateRequest( getRandomMeme, -1, randomMemeDelay, RANDOMMEME );
					return; } }
			else {
				writeLog( 'Random meme error: ' + textStatus, LOG_ERROR );
				writeLog( 'XMLHttpRequest: ' + xhr.responseText, LOG_MOREINFO );	}
			
			localStorage.lastError = textStatus;
			iterateRequest( getRandomMeme, standardIdleTime, randomMemeDelay, RANDOMMEME );
		}    
	});
}

// Simplify setBadge action.
function errorHandler( badgeText ) {
	chrome.browserAction.setBadgeText({ text: badgeText }); }

chrome.extension.onMessage.addListener(
	function( message, sender, sendResponse ) {
		writeLog( 'Request received by Background, validation: ' + message.validation, LOG_INFO );
		// Checking validation for Random Meme
		if( message.validation == 'random-meme' ) {
			writeLog( 'Sending Random Meme to Popup', LOG_INFO );
			sendResponse( randomMeme ); }
		else if( message.validation == 'reload' ) {
			writeLog( 'Reload backgroud page', LOG_INFO );
			this.location.reload(); } });

// When icon is clicked. 
// This event will not fire if the browser action has a popup.
chrome.browserAction.onClicked.addListener( function( selectedTab ) {
	chrome.tabs.getAllInWindow( undefined, function( tabs ) {
		// Check if a tab with Meemi already exixts
		for( var i = 0, tab; tab = tabs[i]; i++ ) {
			if ( tab.url && tab.url.indexOf( 'http://meemi.com/' ) == 0) {
				chrome.tabs.update(tab.id, {'selected': true}); return;	}}
		// Otherwise create it
		chrome.tabs.create({ 'url': 'http://meemi.com/'+ localStorage.username + '/wf' });
	});
});
